package com.hksj.data.tdengine.conf;

import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.Getter;
import lombok.Setter;
import okhttp3.*;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.util.StringUtils;
import org.springframework.util.unit.DataSize;
import java.net.URI;
import java.time.Duration;
import java.util.*;
import java.util.concurrent.ThreadLocalRandom;
import java.util.concurrent.TimeUnit;

@Getter
@Setter
@ConfigurationProperties(prefix = "hk.tdengine")
public class TDengineProperties {

    private String database;

    private RestfulConnector restful = new RestfulConnector();

    private Buffer buffer = new Buffer();

    @Getter
    @Setter
    public static class Buffer {
        private boolean enabled = true;
        private String filePath = "./data/tdengine-buffer";
        private int size = 3000;
    }

    @Getter
    @Setter
    public static class RestfulConnector {

        private List<URI> endpoints = new ArrayList<>(Collections.singletonList(URI.create("http://localhost:6041/")));

        private String username = "root";

        private String password = "taosdata";

        private int maxConnections = Runtime.getRuntime().availableProcessors() * 8;

        private Duration pendingAcquireTimeout = Duration.ofSeconds(10);

        private Duration evictInBackground = Duration.ofSeconds(60);

        private Duration connectionTimeout = Duration.ofSeconds(5);

        private Duration socketTimeout = Duration.ofSeconds(5);

        private DataSize maxInMemorySize = DataSize.ofMegabytes(10);

        // OkHttpClient 实例（线程安全，全局唯一）
        private OkHttpClient httpClient;

        // JSON 工具（用于解析返回结果，可选）
        private final ObjectMapper objectMapper = new ObjectMapper();

        // Line Protocol 媒体类型
        private final MediaType lineProtocolMediaType = MediaType.get("text/plain");

        public RestfulConnector init() {
            OkHttpClient.Builder builder = new OkHttpClient.Builder()
                .connectTimeout(connectionTimeout.toMillis(), TimeUnit.MILLISECONDS)
                .readTimeout(socketTimeout.toMillis(), TimeUnit.MILLISECONDS)
                .writeTimeout(socketTimeout.toMillis(), TimeUnit.MILLISECONDS)
                .connectionPool(new ConnectionPool(maxConnections, 5, TimeUnit.MINUTES));

            // 添加 Basic Auth 拦截器（可选，也可以在每次请求中加）
            if (StringUtils.hasText(username)) {
                builder.addInterceptor(chain -> {
                    Request original = chain.request();
                    Request request = original.newBuilder()
                        .header("Authorization", Credentials.basic(username, password))
                        .build();
                    return chain.proceed(request);
                });
            }

            this.httpClient = builder.build();
            return this;
        }

        /**
         * 随机选择一个 endpoint、更好的负载均衡方式
         */
        public URI selectURI() {
            return endpoints.get(ThreadLocalRandom.current().nextInt(endpoints.size()));
        }

    }

}